package com.hongmeng.teamwork.domain.impl;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.hongmeng.teamwork.convert.TeamworkTaskConvert;
import com.hongmeng.teamwork.convert.UserConvert;
import com.hongmeng.teamwork.domain.ITeamworkTaskDomainService;
import com.hongmeng.teamwork.entity.dto.TeamworkTaskDto;
import com.hongmeng.teamwork.entity.event.TaskMessageEvent;
import com.hongmeng.teamwork.entity.po.*;
import com.hongmeng.teamwork.entity.vo.TeamworkTaskVo;
import com.hongmeng.teamwork.enums.IsDeletedFlagEnum;
import com.hongmeng.teamwork.enums.TaskOptTypeEnum;
import com.hongmeng.teamwork.enums.TaskStatusEnum;
import com.hongmeng.teamwork.service.ITeamworkProjectService;
import com.hongmeng.teamwork.service.ITeamworkTaskService;
import com.hongmeng.teamwork.service.ITeamworkTaskUserRelService;
import com.hongmeng.teamwork.service.ITeamworkUserTaskDirectService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Log4j2
@Service
public class TeamworkTaskDomainServiceImpl implements ITeamworkTaskDomainService {

    @Resource
    private ITeamworkTaskUserRelService teamworkTaskUserRelService;
    @Resource
    private ITeamworkTaskService teamworkTaskService;
    @Resource
    private ITeamworkUserTaskDirectService userTaskDirectService;
    @Resource
    private ITeamworkProjectService projectService;
    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(TeamworkTaskDto teamworkTaskDto) {
        TeamworkTask teamworkTask = TeamworkTaskConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto);
        teamworkTask.setStatus(TaskStatusEnum.UN_START.getCode());
        teamworkTask.setCreatedBy(JSON.toJSONString(teamworkTaskDto.getCreatedUser()));
        teamworkTask.setCreatedTime(LocalDateTime.now());
        teamworkTask.setUpdatedBy(JSON.toJSONString(teamworkTaskDto.getCreatedUser()));
        teamworkTask.setUpdatedTime(LocalDateTime.now());
        teamworkTask.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        teamworkTaskService.insert(teamworkTask);

        // 建立任务-用户关联数据
        TeamworkTaskUserRel teamworkTaskUserRel = new TeamworkTaskUserRel();
        teamworkTaskUserRel.setTaskId(teamworkTask.getId());
        teamworkTaskUserRel.setCreatedTime(LocalDateTime.now());
        teamworkTaskUserRel.setOpenId(teamworkTaskDto.getLeadUser().getOpenId());
        teamworkTaskUserRel.setUserJson(JSON.toJSONString(UserConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto.getLeadUser())));
        teamworkTaskUserRelService.insert(teamworkTaskUserRel);

        // 存储用户、任务转发数据
        teamworkTaskDto.setId(teamworkTask.getId());
        handleUserTaskDirect(teamworkTaskDto);

        // 拉用户进群
        applicationEventPublisher.publishEvent(new TaskMessageEvent(teamworkTaskDto, teamworkTask, TaskOptTypeEnum.CREATE_TASK));
    }

    @Override
    public List<TeamworkTask> queryByOpenId(String openId) {
        // 根据 openId 查询自己所有的任务 id
        TeamworkTaskUserRel teamworkTaskUserRel = new TeamworkTaskUserRel();
        teamworkTaskUserRel.setOpenId(openId);
        List<TeamworkTaskUserRel> taskUserRelList = teamworkTaskUserRelService.queryByCondition(teamworkTaskUserRel);
        List<Long> taskIdList = taskUserRelList.stream().map(TeamworkTaskUserRel::getTaskId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(taskIdList)) return Collections.emptyList();
        // 根据任务 id 集合查询任务集合
        List<TeamworkTask> teamworkTaskList = teamworkTaskService.queryByIdList(taskIdList, null);
        if (log.isInfoEnabled()) {
            log.info("TeamworkTaskDomainServiceImpl.queryByIdList.openId: {} , teamworkTaskList: {}", openId,
                    JSON.toJSONString(teamworkTaskList));
        }
        return teamworkTaskList;
    }

    @Override
    public Long count(TeamworkTask teamworkTask) {
        // 组合数据
        teamworkTask.setIsDeleted(IsDeletedFlagEnum.UN_DELETED.getCode());
        return teamworkTaskService.count(teamworkTask);
    }

    @Override
    public void updateTaskStatus(TeamworkTaskDto teamworkTaskDto) {
        TeamworkTask teamworkTaskDB = teamworkTaskService.queryById(teamworkTaskDto.getId());
        TeamworkTask teamworkTask = new TeamworkTask();
        teamworkTask.setId(teamworkTaskDto.getId());
        teamworkTask.setUpdatedBy(JSON.toJSONString(teamworkTaskDto.getUpdatedUser()));
        teamworkTask.setUpdatedTime(LocalDateTime.now());
        teamworkTask.setStatus(teamworkTaskDto.getStatus());
        teamworkTaskService.update(teamworkTask);
        // 发送消息
        applicationEventPublisher.publishEvent(new TaskMessageEvent(teamworkTaskDto, teamworkTaskDB, TaskOptTypeEnum.UPDATE_STATUS));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void directTask(TeamworkTaskDto teamworkTaskDto) {
        // 任务转发
        directUserTask(teamworkTaskDto);

        // 3.更新任务参数
        TeamworkTask teamworkTask = TeamworkTaskConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto);
        teamworkTask.setUpdatedBy(JSON.toJSONString(teamworkTaskDto.getUpdatedUser()));
        teamworkTask.setUpdatedTime(LocalDateTime.now());
        teamworkTaskService.update(teamworkTask);

        // 发送消息
        TeamworkTask teamworkTaskDB = teamworkTaskService.queryById(teamworkTaskDto.getId());
        applicationEventPublisher.publishEvent(new TaskMessageEvent(teamworkTaskDto, teamworkTaskDB, TaskOptTypeEnum.DIRECT));
    }

    @Override
    public TeamworkTaskVo queryInfo(Long taskId) {
        TeamworkTask teamworkTask = teamworkTaskService.queryById(taskId);
        if (Objects.isNull(teamworkTask)) return null;
        TeamworkUserTaskDirect teamworkUserTaskDirect = new TeamworkUserTaskDirect();
        teamworkUserTaskDirect.setTaskId(taskId);
        List<TeamworkUserTaskDirect> userTaskDirectList = userTaskDirectService.queryByCondition(teamworkUserTaskDirect);
        List<User> taskDirectUser = userTaskDirectList.stream().map(taskDirect -> new Gson().fromJson(taskDirect.getLeaderUserJson(), User.class)).collect(Collectors.toList());
        TeamworkProject teamworkProject = projectService.queryById(teamworkTask.getProjectId());

        TeamworkTaskVo teamworkTaskVo = TeamworkTaskConvert.INSTANCE.convertEntityToVo(teamworkTask);
        teamworkTaskVo.setLeaderUser(taskDirectUser.get(taskDirectUser.size() - 1));
        teamworkTaskVo.setUserDirectRecord(taskDirectUser);
        teamworkTaskVo.setProjectName(teamworkProject.getName());

        return teamworkTaskVo;
    }

    @Override
    public List<TeamworkTask> query(TeamworkTaskDto teamworkTaskDto) {
        return queryByOpenId(teamworkTaskDto);
    }

    private List<TeamworkTask> queryByOpenId(TeamworkTaskDto teamworkTaskDto) {
        // 根据 openId 查询自己所有的任务 id
        List<Long> taskIdList = null;
        if (StringUtils.isNotBlank(teamworkTaskDto.getOpenId())) {
            TeamworkTaskUserRel teamworkTaskUserRel = new TeamworkTaskUserRel();
            teamworkTaskUserRel.setOpenId(teamworkTaskDto.getOpenId());
            List<TeamworkTaskUserRel> taskUserRelList = teamworkTaskUserRelService.queryByCondition(teamworkTaskUserRel);
            taskIdList = taskUserRelList.stream().map(TeamworkTaskUserRel::getTaskId).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(taskIdList)) return Collections.emptyList();
        }

        // 根据任务 id 集合查询任务集合
        TeamworkTask teamworkTask = TeamworkTaskConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto);
        return teamworkTaskService.queryByIdList(taskIdList, teamworkTask);
    }

    @Override
    public void update(TeamworkTaskDto teamworkTaskDto) {
        TeamworkTask teamworkTaskDB = teamworkTaskService.queryById(teamworkTaskDto.getId());
        TeamworkTask teamworkTask = TeamworkTaskConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto);
        teamworkTask.setUpdatedBy(JSON.toJSONString(teamworkTaskDto.getUpdatedUser()));
        teamworkTask.setUpdatedTime(LocalDateTime.now());
        teamworkTaskService.update(teamworkTask);

        TeamworkTaskUserRel teamworkTaskUserRel = teamworkTaskUserRelService.queryTaskId(teamworkTaskDB.getId());
        // 负责人改了需要新增转发记录
        if (!teamworkTaskDto.getLeadUser().getOpenId().equals(teamworkTaskUserRel.getOpenId())) {
            directUserTask(teamworkTaskDto);
        }

        applicationEventPublisher.publishEvent(new TaskMessageEvent(teamworkTaskDto, teamworkTaskDB, TaskOptTypeEnum.UPDATE));
    }

    private void directUserTask(TeamworkTaskDto teamworkTaskDto) {
        // 1.修改任务用户表任务负责人
        TeamworkTaskUserRel teamworkTaskUserRel = new TeamworkTaskUserRel();
        teamworkTaskUserRel.setTaskId(teamworkTaskDto.getId());
        teamworkTaskUserRel.setOpenId(teamworkTaskDto.getLeadUser().getOpenId());
        teamworkTaskUserRel.setUserJson(JSON.toJSONString(UserConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto.getLeadUser())));
        teamworkTaskUserRelService.updateByTaskId(teamworkTaskUserRel);

        // 2.添加任务流转记录
        handleUserTaskDirect(teamworkTaskDto);
    }

    private void handleUserTaskDirect(TeamworkTaskDto teamworkTaskDto) {
        TeamworkUserTaskDirect teamworkUserTaskDirect = new TeamworkUserTaskDirect();
        teamworkUserTaskDirect.setTaskId(teamworkTaskDto.getId());
        teamworkUserTaskDirect.setLeaderUserJson(JSON.toJSONString(UserConvert.INSTANCE.convertDtoToEntity(teamworkTaskDto.getLeadUser())));
        teamworkUserTaskDirect.setCreatedTime(LocalDateTime.now());
        userTaskDirectService.insert(teamworkUserTaskDirect);
    }
}
